package com.terrace.web.tagext.easyui.support;

import javax.servlet.jsp.JspException;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;

import com.terrace.core.constant.ConfigConstant;
import com.terrace.web.tagext.easyui.model.GridColumn;
import com.terrace.web.tagext.easyui.model.GridContainer;
import com.terrace.web.tagext.easyui.model.GridOpt;
import com.terrace.web.tagext.easyui.model.GridToolBar;
import com.terrace.web.tagext.easyui.model.JSFunction;
import com.terrace.web.tagext.easyui.provider.GridAssembleProvider;
import com.terrace.web.tagext.easyui.utils.EasyUIUtils;

/**
 * 网格数据自定义标签
 * @author jiangyg
 *
 */
public abstract class DataGridTagSupport extends GridAssembleProvider {
	
	private static final long serialVersionUID = -7472450443395234643L;

	/**
	 * 表格名称
	 */
	protected String name;

	/**
	 * 表格标题
	 */
	protected String title;

	/**
	 * 标识字段
	 */
	protected String idField;

	/**
	 * 从远程站点请求数据的 URL
	 */
	protected String action;
	
	/**
	 * 请求远程数据的 method 类型
	 */
	protected String method = "post";

	/**
	 * 是否行条纹化--即奇偶行使用不同背景色
	 */
	protected boolean striped = false;
	
	/**
	 * 是否把数据显示在一行里
	 */
	protected boolean nowrap = true;
	
	/**
	 * 是否显示行号
	 */
	protected boolean rownumbers = false;
	
	/**
	 * 是否显示选择框，默认[false]
	 */
	protected boolean checkbox = false;
	
	/**
	 * 是否只允许选中一行
	 */
	protected boolean singleSelect = true;
	
	/**
	 * 当为true时，自动展开/合同列的大小，以适应的宽度，防止横向滚动
	 */
	protected boolean fitColumns = true;
	
	/**
	 * 
	 */
	protected boolean checkOnSelect = true;
	
	/**
	 * 
	 */
	protected boolean selectOnCheck = true;
	
	/**
	 * 初始化页码尺寸
	 */
	protected int pageSize = 10;
	
	/**
	 * 初始化页码
	 */
	protected int pageNumber = 1;

	/**
	 * 是否在底部显示分页栏
	 */
	protected boolean pagination = true;
	
	/**
	 * 是否显示页面列表
	 */
	protected boolean showPageList = true;
	
	/**
	 * 是否显示分页信息
	 */
	protected boolean showPageText = true;
	
	/**
	 * 初始化页面尺寸的选择列表
	 */
	protected int[] pageList;
	
	/**
	 * 是否允许表格自动缩放，以适应父容器
	 */
	protected boolean fit = true;

	/**
	 * 定义的列进行排序
	 */
	protected String sortName;

	/**
	 * 定义列的排序顺序，只能是"递增"或"降序"
	 */
	protected String sortOrder = "asc";

	/**
	 * 定义是否显示刷新按钮
	 */
	protected boolean showRefresh = true;
	
	/**
	 * 定义是否从服务器给数据排序
	 */
	protected boolean remoteSort = true;
	
	/**
	 * 定义是否显示一行页脚
	 */
	protected boolean showFooter = false;
	
	/**
	 * 数据加载完成调用方法
	 */
	protected String onLoadSuccess;

	/**
	 * 单击事件调用方法
	 */
	protected String onClick;

	/**
	 * 双击事件调用方法
	 */
	protected String onDblClick;

	/**
	 * 列表是否自动加载数据
	 */
	protected boolean autoLoadData = true;
	
	/**
	 * 行样式，该函数需要两个参数： 
	 * 					rowIndex： 行的索引，从 0 开始。 
	 * 					rowData： 此行相应的记录
	 */
//	protected String rowStyler = "";
	
	/**
	 * 表格容器
	 */
	protected GridContainer container = new GridContainer();
	
	@Override
	public int doStartTag() throws JspException {
		container.clear();
		container.setGridName(name);
		container.setCheckbox(checkbox);
		container.setAutoLoadData(autoLoadData);
		return EVAL_PAGE;
	}
	
	@Override
	public String createGridContainer() {
		StringBuffer sb = new StringBuffer();
		// 生成div表格容器
		sb.append("<div class=\"easyui-layout\" fit=\"true\">");
		sb.append("<div region=\"center\" fit=\"true\" style=\"padding: 1px;\">");
		sb.append("<div id=\"" + name + "\" name=\"" + name + "\" class=\"easyui-" + gridType() + "\" title=\"" + title + "\" idfield=\"" + idField + "\" fit=\"true\" toolbar=\"#" + name + "ToolBar\">");
		sb.append("</div>");
		sb.append("</div>");
		sb.append("</div>");
		return sb.toString();
	}

	@Override
	public String createInitGridJS() {
		StringBuffer sb = new StringBuffer();
		sb.append("$(\'#" + name + "\')." + gridType() + "({");
		
		// 常用属性组装
		sb.append(this.assembleDataOptions() + ",");
		
		// 列属性生成
		sb.append("columns:[[" + container.transferColumnsToJSObject(false) + "]],");
		sb.append("frozenColumns:[[" + container.transferColumnsToJSObject(true) + "]],");

		// 表格事件
		sb.append(this.createGridEvents());
		
		sb.append("});");
		
		return sb.toString();
	}
	
	@Override
	public String assembleDataOptions() {
		String baseDataOptions = assembleBaseDataOptions();
		String extendDataOptions = assembleExtendDataOptions();
		if (StringUtils.isNotBlank(extendDataOptions)) {
			return baseDataOptions + "," + extendDataOptions;
		}
		return baseDataOptions;
	}

	@Override
	public String assembleBaseDataOptions() {
		StringBuffer sb = new StringBuffer();
		EasyUIUtils.appendDatsOption(sb, "idField", idField);
		EasyUIUtils.appendDatsOption(sb, "url", action);
		EasyUIUtils.appendDatsOption(sb, "method", method);
		EasyUIUtils.appendDatsOption(sb, "striped", striped);
		EasyUIUtils.appendDatsOption(sb, "nowrap", nowrap);
		EasyUIUtils.appendDatsOption(sb, "rownumbers", rownumbers);
		EasyUIUtils.appendDatsOption(sb, "singleSelect", singleSelect);
		EasyUIUtils.appendDatsOption(sb, "checkOnSelect", checkOnSelect);
		EasyUIUtils.appendDatsOption(sb, "selectOnCheck", selectOnCheck);
		EasyUIUtils.appendDatsOption(sb, "pageSize", pageSize);
		EasyUIUtils.appendDatsOption(sb, "pageNumber", pageNumber);
		EasyUIUtils.appendDatsOption(sb, "pagination", pagination);
		EasyUIUtils.appendDatsOption(sb, "showPageList", showPageList);
		EasyUIUtils.appendDatsOption(sb, "showPageText", getPageList());
		EasyUIUtils.appendDatsOption(sb, "fit", fit);
		if (StringUtils.isNotBlank(sortName)) {
			EasyUIUtils.appendDatsOption(sb, "sortName", sortName);
			EasyUIUtils.appendDatsOption(sb, "sortOrder", sortOrder);
		}
		EasyUIUtils.appendDatsOption(sb, "showRefresh", showRefresh);
		EasyUIUtils.appendDatsOption(sb, "remoteSort", remoteSort);
		EasyUIUtils.appendDatsOption(sb, "showFooter", showFooter);
		EasyUIUtils.appendDatsOption(sb, "fitColumns", fitColumns);
		EasyUIUtils.appendDatsOption(sb, "loadMsg", ConfigConstant.value("easyui.datagrid.loadMsg"));
		return EasyUIUtils.substringLastComma(sb).toString();
	}
	
	/**
	 * 常用函数生成
	 * @return
	 */
	@Override
	public String createGridCommonUseFuncs() {
		StringBuffer sb = new StringBuffer();
		
		// 表格查询函数
		sb.append("function " + name + "Search() {var queryParams = $('#" + name + "')." + gridType() + "('options').queryParams;");
		sb.append("$('#" + name + "ToolBar').find('*').each(function() {if($(this).attr('name')){queryParams[$(this).attr('name')] = $(this).val();}});");
		sb.append("$('#" + name + "')." + gridType() + "({url : '" + action + "',pageNumber : 1});}");
		
		// 查询条件重置
		sb.append("function " + name + "SearchReset() {$('#" + name + "ToolBar').find(':input').val('');}");
		// 获取表格选中行
		sb.append("function " + name + "GetSelectRows() {return $('#" + name + "')." + gridType() + "('getChecked');}");
		// 重载表格
		sb.append("var " + name + "ReloadGridTable = function() {$('#" + name + "')." + gridType() + "('reload');};");
		
		return sb.toString();
	}
	
	@Override
	public String createGridEvents() {
		StringBuffer sb = new StringBuffer();
		
		// 当数据加载成功时触发
		JSFunction onLoadSuccessFunc = new JSFunction();
		onLoadSuccessFunc.addFuncParams("data");
		onLoadSuccessFunc.addFuncBody("$(\"#" + name + "\")." + gridType() + "(\"clearSelections\");");
		if (StringUtils.isNotBlank(onLoadSuccess)) {
			onLoadSuccessFunc.addFuncBody(onLoadSuccess + "(data);");
		}
		EasyUIUtils.appendJSObjectProperty(sb, "onLoadSuccess", onLoadSuccessFunc);
		
		// 当用户双击一行时触发
		// 参数包括： 	rowIndex：被双击行的索引，从 0 开始
		// 			rowData：被双击行对应的记录
		if (StringUtils.isNotBlank(onDblClick)) {
			JSFunction onDblClickFunc = new JSFunction();
			onDblClickFunc.addFuncParams("rowIndex", "rowData");
			onDblClickFunc.addFuncBody(onDblClick + "(rowIndex,rowData);");
			EasyUIUtils.appendJSObjectProperty(sb, "onDblClickRow", onDblClickFunc);
		}
		
		// 当用户单击一行时触发
		if (StringUtils.isNotBlank(onClick)) {
			JSFunction onClickFunc = new JSFunction();
			onClickFunc.addFuncParams("rowIndex", "rowData");
			onClickFunc.addFuncBody(onClick + "(rowIndex, rowData);");
			EasyUIUtils.appendJSObjectProperty(sb, "onClickRow", onClickFunc);
		}
		EasyUIUtils.substringLastComma(sb);
		return sb.toString();
	}
	
	/**
	 * 页面加载事件
	 * @return
	 */
	@Override
	public String createGridOnLoadHtmlEvent() {
		StringBuffer sb = new StringBuffer();
		
		// 搜索条件回车事件
		sb.append("$('#" + name + "ToolBar').find(':input').keydown(function(event){if (event.keyCode == 13) {" + name + "Search();}});");
		
		return sb.toString();
	}
	
	/**
	 * grid分页
	 * @param sb
	 * @param grid
	 */
	@Override
	public String createGridPager() {
		StringBuffer sb = new StringBuffer();
		sb.append("$('#" + name + "')." + gridType() + "('getPager').pagination({");
		EasyUIUtils.appendDatsOption(sb, "beforePageText", "");
		EasyUIUtils.appendDatsOption(sb, "afterPageText", "/{pages}");
		if (showPageText) {
			EasyUIUtils.appendDatsOption(sb, "displayMsg", "{from}-{to}共  {total}条");
		}
		EasyUIUtils.appendDatsOption(sb, "showPageList", showPageList);
		EasyUIUtils.appendDatsOption(sb, "showRefresh", showRefresh);
		
		JSFunction jsf = new JSFunction();
		jsf.addFuncParams("pageNumber", "pageSize");
		jsf.addFuncBody("$(this).pagination(\'loading\');$(this).pagination(\'loaded\');");
		EasyUIUtils.appendDatsOption(sb, "onBeforeRefresh", jsf);
		EasyUIUtils.substringLastComma(sb);
		
		sb.append("});");
		return sb.toString();
	}
	
	/**
	 * 生成工具栏
	 * @param sb
	 */
	@Override
	public String createGridToolBar() {
		return container.transferToolbarToLayout();
	}
	
	@Override
	public void addGridToolbar(GridToolBar toolbar) {
		// 权限验证
		if (StringUtils.isNotBlank(toolbar.getPermiCode())) {
			Subject user = SecurityUtils.getSubject();
			if (!user.isPermitted(toolbar.getPermiCode())) {
				return;
			}
		}
		container.addGridToolbar(toolbar);
	}
	
	@Override
	public void addGridOpt(GridOpt opt) {
		// 权限验证
		if (StringUtils.isNotBlank(opt.getPermiCode())) {
			Subject user = SecurityUtils.getSubject();
			if (!user.isPermitted(opt.getPermiCode())) {
				return;
			}
		}
		container.addGridOpt(opt);
	}
	
	@Override
	public void addGridColumn(GridColumn column) {
		container.addGridColumn(column);
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getIdField() {
		return idField;
	}

	public void setIdField(String idField) {
		this.idField = idField;
	}

	public String getAction() {
		return action;
	}

	public void setAction(String action) {
		this.action = action;
	}

	public String getMethod() {
		return method;
	}

	public void setMethod(String method) {
		this.method = method;
	}

	public boolean isStriped() {
		return striped;
	}

	public void setStriped(boolean striped) {
		this.striped = striped;
	}

	public boolean isNowrap() {
		return nowrap;
	}

	public void setNowrap(boolean nowrap) {
		this.nowrap = nowrap;
	}

	public boolean isCheckbox() {
		return checkbox;
	}

	public void setCheckbox(boolean checkbox) {
		this.checkbox = checkbox;
	}

	public boolean isRownumbers() {
		return rownumbers;
	}

	public void setRownumbers(boolean rownumbers) {
		this.rownumbers = rownumbers;
	}

	public boolean isSingleSelect() {
		return singleSelect;
	}

	public void setSingleSelect(boolean singleSelect) {
		this.singleSelect = singleSelect;
	}

	public boolean isFitColumns() {
		return fitColumns;
	}

	public void setFitColumns(boolean fitColumns) {
		this.fitColumns = fitColumns;
	}

	public boolean isCheckOnSelect() {
		return checkOnSelect;
	}

	public void setCheckOnSelect(boolean checkOnSelect) {
		this.checkOnSelect = checkOnSelect;
	}

	public boolean isSelectOnCheck() {
		return selectOnCheck;
	}

	public void setSelectOnCheck(boolean selectOnCheck) {
		this.selectOnCheck = selectOnCheck;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
		this.pageList = new int[] { pageSize * 1, pageSize * 2, 
				pageSize * 3, pageSize * 4 };
	}

	public int getPageNumber() {
		return pageNumber;
	}

	public void setPageNumber(int pageNumber) {
		this.pageNumber = pageNumber;
	}

	public boolean isPagination() {
		return pagination;
	}

	public void setPagination(boolean pagination) {
		this.pagination = pagination;
	}

	public boolean isShowPageList() {
		return showPageList;
	}

	public void setShowPageList(boolean showPageList) {
		this.showPageList = showPageList;
	}

	public boolean isShowPageText() {
		return showPageText;
	}

	public void setShowPageText(boolean showPageText) {
		this.showPageText = showPageText;
	}

	public int[] getPageList() {
		return new int[] { pageSize * 1, pageSize * 2, 
				pageSize * 3, pageSize * 4, pageSize * 5 };
	}

	public void setPageList(int[] pageList) {
		this.pageList = pageList;
	}

	public boolean isFit() {
		return fit;
	}

	public void setFit(boolean fit) {
		this.fit = fit;
	}

	public String getSortName() {
		return sortName;
	}

	public void setSortName(String sortName) {
		this.sortName = sortName;
	}

	public String getSortOrder() {
		return sortOrder;
	}

	public void setSortOrder(String sortOrder) {
		this.sortOrder = sortOrder;
	}

	public boolean isShowRefresh() {
		return showRefresh;
	}

	public void setShowRefresh(boolean showRefresh) {
		this.showRefresh = showRefresh;
	}

	public boolean isRemoteSort() {
		return remoteSort;
	}

	public void setRemoteSort(boolean remoteSort) {
		this.remoteSort = remoteSort;
	}

	public boolean isShowFooter() {
		return showFooter;
	}

	public void setShowFooter(boolean showFooter) {
		this.showFooter = showFooter;
	}

	public String getOnLoadSuccess() {
		return onLoadSuccess;
	}

	public void setOnLoadSuccess(String onLoadSuccess) {
		this.onLoadSuccess = onLoadSuccess;
	}

	public String getOnClick() {
		return onClick;
	}

	public void setOnClick(String onClick) {
		this.onClick = onClick;
	}

	public String getOnDblClick() {
		return onDblClick;
	}

	public void setOnDblClick(String onDblClick) {
		this.onDblClick = onDblClick;
	}

	public boolean isAutoLoadData() {
		return autoLoadData;
	}

	public void setAutoLoadData(boolean autoLoadData) {
		this.autoLoadData = autoLoadData;
	}
	
}
